﻿CREATE SCHEMA pca_ventas;

CREATE TABLE pca_ventas.configuracion_campo_adicional
(
	campo_id varchar(50) NOT NULL,
	nombre varchar(50) NOT NULL,
	visible boolean NOT NULL,
	CONSTRAINT nombre_campo_adicional_pk PRIMARY KEY(campo_id)
);

CREATE TABLE pca_ventas.estado_comprobante
(
	estado_comprobante_id varchar(2) NOT NULL,
	nombre varchar(50) NOT NULL,
	CONSTRAINT estado_comprobante_pk PRIMARY KEY(estado_comprobante_id)
);

------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------Comprobantes de Venta--------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------

CREATE SEQUENCE pca_ventas.seq_comprobante_id;
CREATE TABLE pca_ventas.comprobantes
(
	comprobante_id bigint NOT NULL DEFAULT pca_global.fn_pseudo_encrypt_bigint(nextval('pca_ventas.seq_comprobante_id')::integer),
	sesion_id bigint NOT NULL,
	oficina_id varchar(2) NOT NULL,
	empresa_id varchar(2) NOT NULL,
	documento_id varchar(5) NOT NULL,
	serie integer NOT NULL,
	numero integer NOT NULL,
	cliente_id bigint,
	num_doc_identidad varchar(20),
	nombre_cliente varchar(200) NOT NULL,
	direccion_cliente varchar(200),
	plazo_id varchar(2) NOT NULL,
	fecha_hora_emision timestamp with time zone NOT NULL,
	fecha_hora_vencimiento timestamp with time zone NOT NULL,
	fecha_hora_sistema timestamp with time zone NOT NULL DEFAULT current_timestamp,
	precios_incluyen_igv boolean NOT NULL,
	val_igv numeric(4,2) NOT NULL,--% de Igv
	moneda_id varchar(5) NOT NULL,
	importe_bruto numeric(11,3) NOT NULL DEFAULT 0,
	descuento numeric(11,3) NOT NULL DEFAULT 0,
	valor_venta numeric(11,3) NOT NULL DEFAULT 0,
	impuesto numeric(11,3) NOT NULL DEFAULT 0,
	precio_venta numeric(11,3) NOT NULL DEFAULT 0,
	total_pagos numeric(11,3) NOT NULL DEFAULT 0,
	estado_comprobante_id varchar(2) NOT NULL,
	tipo_cambio_emision numeric(4,2) NOT NULL,
	adicional1 text,
	adicional2 text,
	adicional3 text,
	adicional4 text,
	CONSTRAINT comprobantes_pk PRIMARY KEY(comprobante_id),
	CONSTRAINT sesiones_fkey FOREIGN KEY(sesion_id)
		REFERENCES pca_log.sesiones(sesion_id) MATCH SIMPLE
		ON UPDATE RESTRICT ON DELETE RESTRICT,
	CONSTRAINT oficinas_fkey FOREIGN KEY(oficina_id,empresa_id)
		REFERENCES  pca.oficinas(oficina_id,empresa_id) MATCH SIMPLE
		ON UPDATE RESTRICT ON DELETE RESTRICT,
	CONSTRAINT documentos_fkey FOREIGN KEY(documento_id)
		REFERENCES pca_tablas.documentos(documento_id) MATCH SIMPLE
		ON UPDATE RESTRICT ON DELETE RESTRICT,
	CONSTRAINT clientes_fkey FOREIGN KEY(cliente_id)
		REFERENCES pca_clientes.empresas(empresa_id) MATCH SIMPLE
		ON UPDATE RESTRICT ON DELETE RESTRICT,
	CONSTRAINT plazos_fkey FOREIGN KEY(plazo_id)
		REFERENCES pca_tablas.plazos(plazo_id) MATCH SIMPLE
		ON UPDATE RESTRICT ON DELETE RESTRICT,
	CONSTRAINT monedas_fkey FOREIGN KEY(moneda_id)
		REFERENCES pca_tablas.monedas(moneda_id) MATCH SIMPLE
		ON UPDATE RESTRICT ON DELETE RESTRICT,
	CONSTRAINT estado_comprobante_fkey FOREIGN KEY(estado_comprobante_id)
		REFERENCES pca_ventas.estado_comprobante(estado_comprobante_id) MATCH SIMPLE
		ON UPDATE RESTRICT ON DELETE RESTRICT
);

CREATE SEQUENCE pca_ventas.seq_detalle_id;
CREATE TABLE pca_ventas.detalles_comprobante
(
	detalle_id bigint NOT NULL DEFAULT pca_global.fn_pseudo_encrypt_bigint(nextval('pca_ventas.seq_detalle_id')::integer),
	sesion_id bigint NOT NULL,
	comprobante_id bigint NOT NULL,
	correlativo integer NOT NULL,
	articulo_id bigint,--el ID del articulo 
	codigo varchar(50),--el codigo del articulo o servicio si es que lo tiene
	cantidad numeric(11,3),
	medida varchar(10),
	descripcion text NOT NULL,
	precio_unitario numeric(11,3) NOT NULL,
	precio_costo numeric(11,3),--precio costo referencial del articulo
	precio_total numeric(11,3) NOT NULL,
	CONSTRAINT detalles_comprobante_pk PRIMARY KEY(detalle_id),
	CONSTRAINT sesiones_fkey FOREIGN KEY(sesion_id)
		REFERENCES pca_log.sesiones(sesion_id) MATCH SIMPLE
		ON UPDATE RESTRICT ON DELETE RESTRICT,
	CONSTRAINT comprobante_fkey FOREIGN KEY(comprobante_id)
		REFERENCES pca_ventas.comprobantes(comprobante_id) MATCH SIMPLE
		ON UPDATE RESTRICT ON DELETE RESTRICT,
	CONSTRAINT articulos_fkey FOREIGN KEY(articulo_id)
		REFERENCES pca_almacen.articulos(articulo_id) MATCH SIMPLE
		ON UPDATE RESTRICT ON DELETE RESTRICT
);

------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------Pagos de los comprobantes----------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------

CREATE TABLE pca_ventas.estado_pago
(
	estado_pago_id varchar(2) NOT NULL,
	nombre varchar(50) NOT NULL,
	CONSTRAINT estado_pago_pk PRIMARY KEY(estado_pago_id)
);

CREATE SEQUENCE pca_ventas.seq_pago_id;
CREATE TABLE pca_ventas.pagos_comprobante
(
	pago_id bigint NOT NULL DEFAULT pca_global.fn_pseudo_encrypt_bigint(nextval('pca_ventas.seq_pago_id')::integer),
	sesion_id integer NOT NULL,
	comprobante_id bigint NOT NULL,
	medio_pago_id varchar(5) NOT NULL,
	importe numeric(11,3) NOT NULL,
	fecha_hora_emision timestamp with time zone NOT NULL,	
	fecha_hora_sistema timestamp with time zone NOT NULL DEFAULT current_timestamp,
	estado_pago_id varchar(2) NOT NULL,
	CONSTRAINT pagos_comprobante_fkey PRIMARY KEY(pago_id),
	CONSTRAINT sesiones_fkey FOREIGN KEY(sesion_id)
		REFERENCES pca_log.sesiones(sesion_id) MATCH SIMPLE
		ON UPDATE RESTRICT ON DELETE RESTRICT,
	CONSTRAINT comprobante_fkey FOREIGN KEY(comprobante_id)
		REFERENCES pca_ventas.comprobantes(comprobante_id) MATCH SIMPLE
		ON UPDATE RESTRICT ON DELETE RESTRICT,
	CONSTRAINT medio_pago_fkey FOREIGN KEY(medio_pago_id)
		REFERENCES pca_tablas.medios_pago(medio_pago_id) MATCH SIMPLE
		ON UPDATE RESTRICT ON DELETE RESTRICT,
	CONSTRAINT estado_pago_fkey FOREIGN KEY(estado_pago_id)
		REFERENCES pca_ventas.estado_pago(estado_pago_id) MATCH SIMPLE
		ON UPDATE RESTRICT ON DELETE RESTRICT
);

------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------Triggers--------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------

CREATE OR REPLACE FUNCTION pca_ventas.fn_delete_references_comprobantes() RETURNS trigger AS
$$
BEGIN
	DELETE FROM pca_ventas.detalles_comprobante WHERE comprobante_id = OLD.comprobante_id;
	DELETE FROM pca_ventas.pagos_comprobante WHERE comprobante_id = OLD.comprobante_id;

	RETURN OLD;
END;
$$
LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS tri_delete_references_comprobantes ON pca_ventas.comprobantes;
CREATE TRIGGER tri_delete_references_comprobantes BEFORE DELETE ON pca_ventas.comprobantes
FOR EACH ROW
EXECUTE PROCEDURE pca_ventas.fn_delete_references_comprobantes();

CREATE OR REPLACE FUNCTION pca_ventas.fn_insert_detalle_comprobante() RETURNS trigger AS
$$
BEGIN
	NEW.correlativo = currval('pca_ventas.seq_detalle_id');
	RETURN NEW;
END;
$$
LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS tri_insert_detalle_comprobante ON pca_ventas.detalles_comprobante;
CREATE TRIGGER tri_insert_detalle_comprobante BEFORE INSERT ON pca_ventas.detalles_comprobante
FOR EACH ROW
EXECUTE PROCEDURE pca_ventas.fn_insert_detalle_comprobante();

----------------------------------------------------------------------------------------------------------------
---------------------------------------------DATOS DE INICIO----------------------------------------------------
----------------------------------------------------------------------------------------------------------------

DELETE FROM pca_ventas.estado_comprobante;
INSERT INTO pca_ventas.estado_comprobante VALUES('00','BORRADOR');
INSERT INTO pca_ventas.estado_comprobante VALUES('01','ACTIVO');
INSERT INTO pca_ventas.estado_comprobante VALUES('02','ELIMINADO');
INSERT INTO pca_ventas.estado_comprobante VALUES('99','ANULADO');

DELETE FROM pca_ventas.estado_pago;
INSERT INTO pca_ventas.estado_pago VALUES('00','PENDIENTE DE LIQUIDACION');
INSERT INTO pca_ventas.estado_pago VALUES('01','LIQUIDADO');
INSERT INTO pca_ventas.estado_pago VALUES('02','ANULADO');

----------------------------------------------------------------------------------------------------------------
-------------------------------------------------VISTAS---------------------------------------------------------
----------------------------------------------------------------------------------------------------------------

CREATE OR REPLACE VIEW pca_ventas.vw_comprobantes AS
SELECT
	c.comprobante_id,
	c.sesion_id,
	s.usuario_id,
	c.oficina_id,
	c.empresa_id,
	c.documento_id,
	d.nombre AS documento,
	c.serie,
	c.numero,
	pca_global.fn_get_strserienumero(c.serie,c.numero) AS strserienumero,
	c.cliente_id,
	c.num_doc_identidad,
	c.nombre_cliente,
	c.direccion_cliente,
	c.plazo_id,
	p.nombre AS plazo,
	c.fecha_hora_emision,	
	c.fecha_hora_vencimiento,
	c.fecha_hora_sistema,
	c.precios_incluyen_igv,
	c.val_igv,
	c.moneda_id,
	m.nombre AS moneda,
	m.siglas AS moneda_siglas,
	c.importe_bruto,
	c.descuento,
	c.valor_venta,
	c.impuesto,
	c.precio_venta,
	c.total_pagos,
	c.precio_venta-c.total_pagos as total_deuda,
	c.estado_comprobante_id,
	c.tipo_cambio_emision,
	c.adicional1,
	c.adicional2,
	c.adicional3,
	c.adicional4
FROM
	pca_ventas.comprobantes c
INNER JOIN
	pca_tablas.documentos d
ON
	(c.documento_id=d.documento_id)
INNER JOIN
	pca_tablas.plazos p
ON
	(c.plazo_id = p.plazo_id)
INNER JOIN
	pca_tablas.monedas m
ON
	(c.moneda_id=m.moneda_id)
INNER JOIN
	pca_log.sesiones s
ON
	(c.sesion_id=s.sesion_id);

CREATE OR REPLACE VIEW pca_ventas.vw_pagos_comprobante AS
SELECT
	p.pago_id,
	p.sesion_id,
	p.comprobante_id,
	p.medio_pago_id,
	m.nombre AS medio_pago,
	p.importe,
	p.fecha_hora_emision,	
	p.fecha_hora_sistema,
	p.estado_pago_id,
	e.nombre as estado_pago
FROM
	pca_ventas.pagos_comprobante p
INNER JOIN
	pca_tablas.medios_pago m
ON
	(p.medio_pago_id=m.medio_pago_id)
INNER JOIN
	pca_ventas.estado_pago e
ON
	(p.estado_pago_id=e.estado_pago_id);

--Usar esta vista para buscar comprobante a asignar
CREATE OR REPLACE VIEW pca_ventas.vw_comprobantes_asignar AS
SELECT
	c.comprobante_id,
	c.oficina_id,
	c.empresa_id,
	c.documento_id,
	c.serie,
	c.numero,
	d.nombre || ' N°' || pca_global.fn_get_strserienumero(c.serie,c.numero) AS title,
	c.num_doc_identidad || ' ' || c.nombre_cliente AS cliente,
	c.fecha_hora_emision,	
	m.siglas || ' ' || c.precio_venta AS total,
	c.estado_comprobante_id
FROM
	pca_ventas.comprobantes c
INNER JOIN
	pca_tablas.documentos d
ON
	(c.documento_id=d.documento_id)
INNER JOIN
	pca_tablas.monedas m
ON
	(c.moneda_id=m.moneda_id)
INNER JOIN
	pca_log.sesiones s
ON
	(c.sesion_id=s.sesion_id);

-----------------------------------------------------------------------------------------------------
------------------------------------Datos de Inicio--------------------------------------------------
-----------------------------------------------------------------------------------------------------

DELETE FROM pca_ventas.configuracion_campo_adicional;
INSERT INTO pca_ventas.configuracion_campo_adicional VALUES 
('adicional1','Guia(s) Remision',true),
('adicional2','Orden(es) de Servicio',true),
('adicional3','Sujeto a detracción',true),
('adicional4','Referencia',true);